package com.tanhua.manage.service;

import cn.hutool.crypto.SecureUtil;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.tanhua.manage.domain.Admin;
import com.tanhua.manage.exception.BusinessException;
import com.tanhua.manage.mapper.AdminMapper;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import org.apache.commons.collections.map.HashedMap;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;

import java.time.Duration;
import java.util.HashMap;
import java.util.Map;

@Service
public class AdminService  extends ServiceImpl<AdminMapper,Admin>{

    @Autowired
    private RedisTemplate<String,String> redisTemplate;

    private static final String MANAGE_CAP = "MANAGE_CAP_";
    private static final String MANAGE_TOKEN = "MANAGE_TOKEN_";


    @Value("${tanhua.secret}")
    private String secret;

    //作用：保存验证码到redis中
    public void saveCap(String uuid, String code) {
        String key = MANAGE_CAP+uuid;
        redisTemplate.opsForValue().set(key,code, Duration.ofMinutes(2)); //两分钟过期
    }

    /**
     * 登陆的方法
     * @param paramMap
     * @return
     */
    public ResponseEntity login(Map<String, String> paramMap) throws BusinessException {
//        1.获取请求参数
        String username = paramMap.get("username");
        String password = paramMap.get("password");
        String verificationCode = paramMap.get("verificationCode");
        String uuid = paramMap.get("uuid");
//        2.判断用户名密码是否为空
        if(StringUtils.isEmpty(username)||StringUtils.isEmpty(password)){
            //以前的做法
            //return ResponseEntity.status(401).body("用户名或者密码不能为空");
            //给大家演示新做法：自定义异常
            throw new BusinessException("用户名或者密码不能为空");
        }
//        2.1 判断用户名是否存在
        Admin admin = query().eq("username", username).one();
        if(admin==null){
            throw new BusinessException("该用户不存在");
        }

//        2.2 判断密码是否正确
        if(!admin.getPassword().equals(SecureUtil.md5(password))){
            throw new BusinessException("密码错误");
        }

//        3.判断验证码
//        3.1 验证码参数非空判断
        if(StringUtils.isEmpty(verificationCode)){
            throw new BusinessException("验证码不能为空");
        }
//        3.2 校验验证码
        //取出系统的验证码
        String capKey = MANAGE_CAP+uuid;
        //reids中存储的验证码
        String authCode = redisTemplate.opsForValue().get(capKey);
        if(!verificationCode.equalsIgnoreCase(authCode)){
            throw new BusinessException("验证码输入错误");
        }
//        4.删除验证码
        redisTemplate.delete(capKey);
//        5.生成token
        Map<String,Object> map = new HashMap<>();
        map.put("id",admin.getId());
        map.put("uesrname",admin.getUsername());
        String token = Jwts.builder().setClaims(map).signWith(SignatureAlgorithm.HS256, secret).compact();
//        6.用户对象存入redis
        String adminJson = JSON.toJSONString(admin);
        String tokenKey = MANAGE_TOKEN+token;
        redisTemplate.opsForValue().set(tokenKey, adminJson,Duration.ofHours(4));
//        7.返回结果
        Map<String,String> resultMap = new HashedMap();
        resultMap.put("token",token);
        return ResponseEntity.ok(resultMap);
    }


    // 根据登录token，获取用户对象
    public Admin findUserByToken(String token) {
        String userStr = redisTemplate.opsForValue().get(MANAGE_TOKEN + token);
        if(userStr == null) {
            return null;
        }
        // 续期
        redisTemplate.opsForValue().set(MANAGE_TOKEN + token, userStr, Duration.ofHours(4));
        return JSON.parseObject(userStr, Admin.class);
    }



    //退出登陆
    public ResponseEntity logout(String token) {
        String tokenKey = MANAGE_TOKEN+token;
        redisTemplate.delete(tokenKey);
        return ResponseEntity.ok(null);
    }
}
